package com.logos.ruralrevitalization.service.impl;

import com.alibaba.fastjson.JSON;
import com.logos.ruralrevitalization.constant.LoginConstant;
import com.logos.ruralrevitalization.constant.RedisConstant;
import com.logos.ruralrevitalization.constant.RegisterConstant;
import com.logos.ruralrevitalization.converter.AuthUserConverter;
import com.logos.ruralrevitalization.converter.ProductOrderConverter;
import com.logos.ruralrevitalization.converter.ShoppingCartConverter;
import com.logos.ruralrevitalization.entity.*;
import com.logos.ruralrevitalization.enums.IsDeleteFlagEnum;
import com.logos.ruralrevitalization.enums.UserSexEnum;
import com.logos.ruralrevitalization.exception.LoginException;
import com.logos.ruralrevitalization.mapper.*;
import com.logos.ruralrevitalization.redis.RedisUtil;
import com.logos.ruralrevitalization.req.AuthUserReq;
import com.logos.ruralrevitalization.resp.ProductOrderResp;
import com.logos.ruralrevitalization.resp.RuralShowResp;
import com.logos.ruralrevitalization.resp.ShoppingCartResp;
import com.logos.ruralrevitalization.service.AuthUserService;
import com.logos.ruralrevitalization.utils.JwtPlusTool;
import com.logos.ruralrevitalization.utils.Md5Utils;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 用户表(AuthUser)表服务实现类
 *
 * @author rose
 * @since 2025-03-24 22:03:03
 */
@Service("authUserService")
@Slf4j
public class AuthUserServiceImpl implements AuthUserService {
    @Resource
    private AuthUserMapper authUserMapper;

    @Resource
    private ProductOrderMapper productOrderMapper;

    @Resource
    private OrderCartMappingMapper orderCartMappingMapper;

    @Resource
    private ShoppingCartMapper shoppingCartMapper;

    @Resource
    private AgriculturalProductMapper agriculturalProductMapper;

    @Resource
    private OrderProductMappingMapper orderProductMappingMapper;

    @Resource
    private TouristAttractionsMapper touristAttractionsMapper;

    @Resource
    private JwtPlusTool jwtPlusTool;

    @Resource
    private RedisUtil redisUtil;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public AuthUser queryById(Long id) {
        return this.authUserMapper.queryById(id);
    }

//    /**
//     * 分页查询
//     *
//     * @param authUser 筛选条件
//     * @param pageRequest      分页对象
//     * @return 查询结果
//     */
//    @Override
//    public Page<AuthUser> queryByPage(AuthUser authUser, PageRequest pageRequest) {
//        long total = this.authUserMapper.count(authUser);
//        return new PageImpl<>(this.authUserMapper.queryAllByLimit(authUser, pageRequest), pageRequest, total);
//    }

    /**
     * 新增数据
     *
     * @param authUser 实例对象
     * @return 实例对象
     */
    @Override
    public AuthUser insert(AuthUser authUser) {
        this.authUserMapper.insert(authUser);
        return authUser;
    }

    /**
     * 修改数据
     *
     * @param authUser 实例对象
     * @return 实例对象
     */
    @Override
    public AuthUser update(AuthUser authUser) {
        this.authUserMapper.update(authUser);
        return this.queryById(authUser.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long id) {
        return this.authUserMapper.deleteById(id) > 0;
    }

    @Override
    public String login(AuthUserReq authUserReq) {
        if (log.isInfoEnabled()) {
            log.info("AuthUserService.java.login.authUserRequest:{}", JSON.toJSONString(authUserReq));
        }
        // 查询是否存在当前用户
        AuthUser authUser = new AuthUser();
        authUser.setPhone(Md5Utils.encode(authUserReq.getPhone()));
        authUser.setUserType(authUserReq.getUserType());
        authUser = authUserMapper.queryByCondition(authUser);
        if (authUser == null) {
            throw new LoginException(LoginConstant.USER_NOEXIST);
        }
        authUser.setPassword(Md5Utils.encode(authUserReq.getPassword()));
        authUser = authUserMapper.queryByCondition(authUser);
        if (authUser == null) {
            throw new LoginException(LoginConstant.PASSWORD_ERROR);
        }
        String token = jwtPlusTool.createToken(String.valueOf(authUser.getId()), Duration.ofDays(30L));
        return token;
    }

    @Override
    public String register(AuthUserReq authUserReq) {
        if (log.isInfoEnabled()) {
            log.info("AuthUserService.java.login.authUserRequest:{}", JSON.toJSONString(authUserReq));
        }
        // 获取 Redis 中的验证码
        String lowCaptcha = authUserReq.getCaptcha().toLowerCase();
        String redisCaptcha = redisUtil.get(RedisConstant.CAPTCHA_CODE + lowCaptcha);

        // 检查 Redis 中是否存储了验证码
        if (redisCaptcha == null || !redisCaptcha.equalsIgnoreCase(lowCaptcha)) {
            throw new LoginException(LoginConstant.CAPTCHA_ERROR);
        }

        // 查询是否存在当前用户
        AuthUser authUser = new AuthUser();
        authUser.setPhone(Md5Utils.encode(authUserReq.getPhone()));
        authUser.setUserType(authUserReq.getUserType());
        authUser = authUserMapper.queryByCondition(authUser);
        if (authUser != null) {
            throw new LoginException(RegisterConstant.PHONE_EXIST_USER_TYPE);
        }
        authUser = AuthUserConverter.INSTANCE.convertReqToEntity(authUserReq);
        authUser.setPassword(Md5Utils.encode(authUserReq.getPassword()));
        authUser.setPhone(Md5Utils.encode(authUserReq.getPhone()));
        authUser.setUserType(authUserReq.getUserType());
        authUser.setSex(UserSexEnum.MALE.getCode());
        authUser.setCreatedTime(new Date());
        int count = authUserMapper.insert(authUser);
        if (count <= 0) {
            throw new LoginException(RegisterConstant.REGISTER_ERROR);
        }
        String token = jwtPlusTool.createToken(String.valueOf(authUser.getId()), Duration.ofDays(30L));
        return token;
    }

    @Override
    public Boolean updateInfo(AuthUserReq authUserReq) {
        // 判断用户是否更改密码
        if (authUserReq.getPassword() != null) {
            authUserReq.setPassword(Md5Utils.encode(authUserReq.getPassword()));
        }
        AuthUser authUser = AuthUserConverter.INSTANCE.convertReqToEntity(authUserReq);
        return authUserMapper.update(authUser) > 0;
    }

    /**
     * 查询当前用户的订单
     */
    @Override
    public List<ProductOrderResp> queryOrder(Long userId) {
        List<ProductOrderResp> productOrderRespList = new LinkedList<>();
        ProductOrder productOrder = new ProductOrder();
        productOrder.setCustomerId(userId);
        productOrder.setIsDeleted(IsDeleteFlagEnum.UN_DELETED.getCode());
        // 查询当前用户的所有订单
        List<ProductOrder> productOrderList = productOrderMapper.queryByCondition(productOrder);
        // 查询每个订单所有的购物车信息
        productOrderList.forEach(item -> {
            Long orderId = item.getId();
            OrderCartMapping orderCartMapping = new OrderCartMapping();
            orderCartMapping.setOrderId(orderId);
            orderCartMapping.setIsDeleted(IsDeleteFlagEnum.UN_DELETED.getCode());
            // 查询出该用户的所有订单数据，同时按照下单时间进行降序
            List<OrderCartMapping> orderCartMappingList = orderCartMappingMapper.queryByCondition(orderCartMapping);
            // 拿到订单对应的购物车id
            List<Long> shoppingCartIds = orderCartMappingList.stream().map(OrderCartMapping::getCartId).collect(Collectors.toList());
            // 查询购物车信息
            List<ShoppingCart> shoppingCartList = shoppingCartMapper.queryByIdList(shoppingCartIds);
            List<ShoppingCartResp> shoppingCartRespList = new LinkedList<>();
            shoppingCartList.forEach(shoppingCart -> {
                ShoppingCartResp shoppingCartResp = ShoppingCartConverter.INSTANCE.convertEntityToResp(shoppingCart);
                // 查询购物车对应的商品信息
                Long productId = shoppingCartResp.getProductId();
                AgriculturalProduct agriculturalProduct = agriculturalProductMapper.queryById(productId);
                shoppingCartResp.setProductName(agriculturalProduct.getName());
                shoppingCartResp.setProductPrice(agriculturalProduct.getPrice());
                shoppingCartResp.setProductAvatar(agriculturalProduct.getAvatar());
                shoppingCartRespList.add(shoppingCartResp);
            });
            // 组装返回结果
            ProductOrderResp productOrderResp = ProductOrderConverter.INSTANCE.convertEntityToResp(item);
            productOrderResp.setShoppingCartRespList(shoppingCartRespList);
            productOrderRespList.add(productOrderResp);
        });
        // 按订单创建时间进行排序
        productOrderRespList.sort(Comparator.comparing(ProductOrderResp::getCreatedTime).reversed());
        return productOrderRespList;
    }

    @Override
    public RuralShowResp show(Long userId) {
        // 先查询缓存中是否存在
        if (redisUtil.exist(RedisConstant.RURAL_SHOW + userId)) {
            String jsonStr = redisUtil.get(RedisConstant.RURAL_SHOW + userId);
            RuralShowResp ruralShowResp = JSON.parseObject(jsonStr, RuralShowResp.class);
            return ruralShowResp;
        }

        RuralShowResp ruralShowResp = new RuralShowResp();
        // 查询出当前农户相关农产品数据
        AgriculturalProduct agriculturalProduct = new AgriculturalProduct();
        agriculturalProduct.setSupplierId(userId);
        List<AgriculturalProduct> agriculturalProductList = agriculturalProductMapper.queryByCondition(agriculturalProduct);
        ruralShowResp.setProductTotalCount(agriculturalProductList.size());
        agriculturalProduct.setIsDeleted(IsDeleteFlagEnum.UN_DELETED.getCode());
        List<AgriculturalProduct> productList = agriculturalProductMapper.queryByCondition(agriculturalProduct);
        ruralShowResp.setProductCount(productList.size());
        // 查询与该用户相关的订单总数
        // 拿到所有农产品的id
        List<Long> productIds = agriculturalProductList.stream()
                .map(AgriculturalProduct::getId)
                .collect(Collectors.toList());
        // 根据农产品id查询出该农户的订单总数
        Integer orderTotalCount = orderProductMappingMapper.queryCountByProductIds(productIds);
        ruralShowResp.setOrderTotalCount(orderTotalCount);

        // 查询出该农户的销售总额
        // 根据农产品id查询出购物车中所有与该农产品相关的数据，is_deleted = 1
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.queryByCommpleted(productIds);
        BigDecimal totalSales = calSales(shoppingCartList);
        totalSales = totalSales.setScale(2, BigDecimal.ROUND_HALF_UP);
        log.info("totalSales:{}", totalSales);
        ruralShowResp.setTotalSales(totalSales.doubleValue());

        // 查询本月销售总额
        List<ShoppingCart> shoppingCartListMonth = shoppingCartMapper.queryByCommpletedMonth(productIds);
        BigDecimal monthSales = calSales(shoppingCartListMonth);
        monthSales = monthSales.setScale(2, BigDecimal.ROUND_HALF_UP);
        log.info("monthSales:{}", monthSales);
        ruralShowResp.setMonthSales(monthSales.doubleValue());

        // 查询景点数据
        TouristAttractions touristAttractions = new TouristAttractions();
        touristAttractions.setSupplierId(userId);
        List<TouristAttractions> touristAttractionsTotalList = touristAttractionsMapper.queryByCondition(touristAttractions);
        ruralShowResp.setAttractionTotalCount(touristAttractionsTotalList.size());
        touristAttractions.setIsDeleted(IsDeleteFlagEnum.UN_DELETED.getCode());
        List<TouristAttractions> touristAttractionsList = touristAttractionsMapper.queryByCondition(touristAttractions);
        ruralShowResp.setAttractionCount(touristAttractionsList.size());
        // 存入redis
        redisUtil.setNx(RedisConstant.RURAL_SHOW + userId, JSON.toJSONString(ruralShowResp), 2L, TimeUnit.MINUTES);
        return ruralShowResp;
    }


    /**
     * 查询农户的订单信息
     */
    @Override
    public List<ProductOrderResp> queryRuralOrder(Long userId) {
        // 查询缓存中是否存在
        if (redisUtil.exist(RedisConstant.RURAL_SHOW_ORDER + userId)) {
            String jsonStr = redisUtil.get(RedisConstant.RURAL_SHOW_ORDER + userId);
            List<ProductOrderResp> result = JSON.parseArray(jsonStr, ProductOrderResp.class);
            return result;
        }
        // 准备数据
        List<ProductOrderResp> productOrderRespList = new LinkedList<>();
        // 查询出当前农户相关农产品数据
        AgriculturalProduct agriculturalProduct = new AgriculturalProduct();
        agriculturalProduct.setSupplierId(userId);
        List<AgriculturalProduct> productList = agriculturalProductMapper.queryByCondition(agriculturalProduct);
        List<Long> productIds = productList.stream()
                .map(AgriculturalProduct::getId)
                .collect(Collectors.toList());
        // 根据农产品id查出该农户的订单id
        List<Long> orderIds = orderProductMappingMapper.queryOrderIdsByProductIds(productIds);
        orderIds.forEach(orderId -> {
            ProductOrder productOrder = productOrderMapper.queryById(orderId);
            ProductOrderResp productOrderResp = ProductOrderConverter.INSTANCE.convertEntityToResp(productOrder);
            // 根据订单id查询出与该农户相关的购物车id
            List<Long> shoppingCartIds = orderCartMappingMapper.queryCarIdsByOrderId(orderId);
            // 根据购物车id与农产品id查询出与该农户相关的记录
            List<ShoppingCart> shoppingCartList = shoppingCartMapper.queryByIdsAndProductIds(shoppingCartIds, productIds);
            List<ShoppingCartResp> shoppingCartRespList = new LinkedList<>();
            shoppingCartList.forEach(item -> {
                ShoppingCartResp shoppingCartResp = ShoppingCartConverter.INSTANCE.convertEntityToResp(item);
                Long productId = item.getProductId();
                AgriculturalProduct tmpProduct = agriculturalProductMapper.queryById(productId);
                shoppingCartResp.setProductAvatar(tmpProduct.getAvatar());
                shoppingCartResp.setProductName(tmpProduct.getName());
                shoppingCartResp.setProductPrice(tmpProduct.getPrice());
                shoppingCartRespList.add(shoppingCartResp);
            });
            productOrderResp.setShoppingCartRespList(shoppingCartRespList);
            productOrderRespList.add(productOrderResp);
        });
        // 按照时间排序
        productOrderRespList.sort(
                Comparator.comparing(
                        ProductOrderResp::getCreatedTime,
                        Comparator.nullsLast(Comparator.reverseOrder())
                )
        );

        // 存入缓存
        redisUtil.setNx(RedisConstant.RURAL_SHOW_ORDER + userId, JSON.toJSONString(productOrderRespList), 2L, TimeUnit.MINUTES);
        return productOrderRespList;
    }

    @NotNull
    private BigDecimal calSales(List<ShoppingCart> shoppingCartList) {
        // 查询出对应农产品的单价，并计算总价
        BigDecimal totalSales = new BigDecimal(0.0);
        for (ShoppingCart item : shoppingCartList) {
            Long productId = item.getProductId();
            AgriculturalProduct tmpProduct = agriculturalProductMapper.queryById(productId);
            Double price = tmpProduct.getPrice();
            Integer quantity = item.getQuantity();
            BigDecimal productTotalPrice = new BigDecimal(price).multiply(new BigDecimal(quantity));
            totalSales = totalSales.add(productTotalPrice);
        }
        return totalSales;
    }
}
